﻿using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using PmSoft.Core;
using PmSoft.Web.Abstractions.ErrorCode;

namespace PmSoft.Web.Abstractions.Filters;

/// <summary>
/// 全局异常过滤器，用于捕获和处理应用程序中的未处理异常。
/// </summary>
public class GlobalExceptionFilter : IExceptionFilter
{
	private readonly ILogger<GlobalExceptionFilter> _logger;
	private readonly IWebHostEnvironment _env;

	/// <summary>
	/// 构造函数，注入日志记录器和环境信息。
	/// </summary>
	/// <param name="logger">日志记录器。</param>
	/// <param name="env">环境信息。</param>
	public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> logger, IWebHostEnvironment env)
	{
		_logger = logger ?? throw new ArgumentNullException(nameof(logger));
		_env = env ?? throw new ArgumentNullException(nameof(env));
	}

	/// <summary>
	/// 处理异常。
	/// </summary>
	/// <param name="context">异常上下文。</param>
	public void OnException(ExceptionContext context)
	{
		// 记录异常日志
		LogException(context);

		// 处理异常并返回响应
		HandleException(context);

		// 标记异常已处理
		context.ExceptionHandled = true;
	}

	/// <summary>
	/// 记录异常日志。
	/// </summary>
	/// <param name="context">异常上下文。</param>
	private void LogException(ExceptionContext context)
	{
		var requestUrl = context.HttpContext.Request.GetDisplayUrl();
		var exception = context.Exception;

		_logger.LogError(exception, "服务器异常，请求URL：{RequestUrl}，异常信息：{Message}", requestUrl, exception.Message);
	}

	/// <summary>
	/// 处理异常并设置响应结果。
	/// </summary>
	/// <param name="context">异常上下文。</param>
	private void HandleException(ExceptionContext context)
	{
		var exception = context.Exception;

		if (exception is PmSoftException pmSoftException)
		{
			var errorCodeDefinition = ErrorCodeManager.GetError(pmSoftException.Code);
			// 处理特定类型的异常
			context.Result = new JsonResult(ApiResult.Error(errorCodeDefinition.Code, pmSoftException.Message))
			{
				StatusCode = errorCodeDefinition.HttpStatus // Bad Request
			};
		}
		else
		{
			var errorCodeDefinition = ErrorCodeManager.GetError("500ERROR");
			// 处理其他异常
			var errorMessage = _env.IsDevelopment()
				? $"错误信息：{exception.Message}，堆栈信息：{exception.StackTrace}"
				: errorCodeDefinition.Message;

			context.Result = new JsonResult(ApiResult.Error(errorCodeDefinition.Code, errorMessage))
			{
				StatusCode = StatusCodes.Status500InternalServerError // Internal Server Error
			};
		}
	}
}